var mycanvas = document.getElementById("mycanvas");
var sleepTime = 3000; //向量之间的停顿时间讲个（毫秒）
var time1 = 4000; //线条之间的绘制间隔时间，毫秒为单位，1000毫秒为1秒
var colorArrage = ["#FF0000", "#0000FF", "#FFFF00", "#00FFFF", "#FF00FF", "#990000"]; //线条颜色集合
/**
 * 
 *color:#000000;黑色
 *color:#FF0000;红色
 *color:#0000FF;蓝色
 *color:#FFFF00;黄色
 *color:#00FFFF;青色
 *color:#FF00FF;紫色
 *color:#990000;褐色
 */
var lastColor = 0; //保存上一次操作选中颜色，确保相邻两次操作颜色不同
mycanvas.width = 500; //画布宽度
mycanvas.height = 500; //画布高度
var context = mycanvas.getContext("2d");
var cunit = 5; //画布单位刻度
var v1 = 100; //直线绘制间隔时间，即速度毫秒为单位
var c1 = 3 * cunit; //刻度间隔

/*
 *颜色选择器，用于随机从colorArrage选取颜色值
 */
function selectColor() {
	i = Math.floor(Math.random() * colorArrage.length);
	if (i == lastColor) {
		return selectColor();
	} else {
		lastColor = i;
		return colorArrage[i];

	}
}

/*
 *暂停函数定义
 */
function Sleep(ms) {
	return new Promise(resolve => setTimeout(resolve, ms));
}

/*
*下面是一些数学运算函数的重写方法
*这样重写，便于在输入框中使用
*/
function sqrt(num) {
    return Math.sqrt(num);
}

function pow(num1, num2) {
    return Math.pow(num1, num2);
}

function cos(num) {
    return Math.cos(num);
}

function sin(num) {
    return Math.sin(num);
}

function tan(num) {
    return Math.tan(num);
}

/*
 *虚线绘制方法,len为虚线间隔，默认为5像素(静态绘制)
 */
function drowDashedLine(context1, x1, y1, x2, y2, color, len) {
	color = color == undefined ? "#000000" : color; //虚线颜色，默认黑色
	context1.save();
	context1.globalAlpha = 1; //虚线透明度
	context1.strokeStyle = color;
	context1.beginPath();
	len = len == undefined ? 5 : len;
	dx = x2 * c1 - x1 * c1;
	dy = y2 * c1 - y1 * c1;
	numDashes = Math.floor(Math.sqrt(dx * dx + dy * dy) / len);
	for (i = 0; i < numDashes; i++) {
		if (i % 2 == 0) {
			context1.moveTo(x1 * c1 + (dx / numDashes) * i, -y1 * c1 - (dy / numDashes) * i);
		} else {
			context1.lineTo(x1 * c1 + (dx / numDashes) * i, -y1 * c1 - (dy / numDashes) * i);

		}
	}
	context1.stroke();
	context1.closePath();
	context1.restore();
}

/*
 *(静态)实线绘制
 *(x1,y1)向(x2,y2)
 */
function drowLine(context, x1, y1, x2, y2, mycolor) {
	context.save();
	mycolor = mycolor == undefined ? "black" : mycolor;
	context.strokeStyle = mycolor;
	context.beginPath();
	context.moveTo(x1 * c1, -y1 * c1);
	context.lineTo(x2 * c1, -y2 * c1);
	context.stroke();
	context.closePath();
	context.restore();

}

/*
 *动态虚线绘制方法,len为虚线间隔，默认为5像素
 *(x1,y1)向(x2,y2)
 */
async function drowDashedLine2(context1, x1, y1, x2, y2, color, len) {
	context1.save();
	context1.globalAlpha = 1; //虚线透明度
	color = color == undefined ? '#000000' : color;
	context1.strokeStyle = color;
	context1.beginPath();
	len = len == undefined ? 5 : len;
	dx = x2 * c1 - x1 * c1;
	dy = y2 * c1 - y1 * c1;
	numDashes = Math.floor(Math.sqrt(dx * dx + dy * dy) / len);
	for (i = 0; i < numDashes; i++) {
		if (i % 2 == 0) {
			context1.moveTo(x1 * c1 + (dx / numDashes) * i, -y1 * c1 - (dy / numDashes) * i);
		} else {
			context1.lineTo(x1 * c1 + (dx / numDashes) * i, -y1 * c1 - (dy / numDashes) * i);
			await Sleep(v1);
			context1.stroke();
		}
	}
	context1.closePath();
	context1.restore();
}

/*
 *二维
 *矢量绘制方法（矢量都从原点出发）静态绘制
 */
function drowVector(context1, x, y, lineColor) {
	lineColor = lineColor == undefined ? selectColor() : lineColor;

	context1.save();
	context1.strokeStyle = lineColor;
	context1.beginPath();
	context1.moveTo(0, 0);
	context1.lineTo(x * c1, -y * c1);
	context1.stroke();
	context1.closePath();
	context1.restore();
}

/*
 *辅助画出动态直线函数
 */
function setLineTime(context1, i, num, dx, dy) {
	if (i < num) {
		setTimeout(function () {
			context1.beginPath();
			context1.moveTo(0, 0);
			context1.lineTo(0 + (dx / num) * i, -(0 + (dy / num) * i));
			context1.stroke();
			context1.closePath();
			setLineTime(context1, i + 1, num, dx, dy);
		}, v1);
	}
}


/*
 *动态矢量绘制,len为画线长度，通过嵌套执行setTimeout控制停顿
 *原点出发
 */
function drowVector2(context1, x, y, color, len) {
	len = len == undefined ? 5 : len; //默认每次向前延伸5个单位
	color = color == undefined ? selectColor() : color;
	context1.strokeStyle = color;
	dx = x * c1;
	dy = y * c1;
	num = Math.floor(Math.sqrt(dx * dx + dy * dy) / len); //移动数量
	setLineTime(context1, 0, num, dx, dy);
}


/*
 *二维动态矢量绘制,通过Sleep控制停顿
 *从x0,y0出发（默认原点出发）
 */
async function drowVector3(context1, x, y, x0, y0, color, len) {
	context1.beginPath();
	len = len == undefined ? 5 : len; //默认每次向前延伸5个单位
	x0 = x0 == undefined ? 0 : x0;
	y0 = y0 == undefined ? 0 : y0;
	color = color == undefined ? selectColor() : color;
	context1.strokeStyle = color;
	dx = x * c1 - x0 * c1;
	dy = y * c1 - y0 * c1;
	num = Math.floor(Math.sqrt(dx * dx + dy * dy) / 5);

	for (var i = 0; i <= num; i++) {
		context1.moveTo(x0 * c1, -y0 * c1);

		context1.lineTo(x0 * c1 + (dx / num) * i, -(y0 * c1 + (dy / num) * i));
		context.stroke();
		await Sleep(v1);
	}
	context1.closePath();
}


/*
 *绘制3D动态虚线
 *不好用,最好别用
 */
function drowDashedLine3D(context, x1, y1, z1, x2, y2, z2, color) {
	color = color == undefined ? '#000000' : color;
	drowDashedLine2(context, -x1 + y1, -x1 + z1, -x2 + y2, -x2 + z2, color);
}

/*
 *3D坐标转换2D坐标
 */
function toChange(x, y, z) {
	x = x * 1;
	y = y * 1;
	z = z * 1;
	var xx = [];
	xx[0] = -x + y;
	xx[1] = -x + z;
	return xx;
}

/*
 *三维立方体(边框)绘制
 *根据x,y,z从原点（0,0,0,）绘制到（x,y,z）的立方体
 */
function drowCube(context, x1, y1, z1) {
	drowDashedLine(context, 0, 0, -x1, -x1); //x
	drowDashedLine(context, 0, 0, y1, 0); //y
	drowDashedLine(context, 0, 0, 0, z1); //z
	drowDashedLine(context, -x1, -x1, y1 - x1, -x1); //xy横
	drowDashedLine(context, y1, 0, y1 - x1, -x1); //xy竖
	drowDashedLine(context, y1, 0, y1, z1); //yz竖
	drowDashedLine(context, -x1, -x1, -x1, -x1 + z1); //xz竖
	drowDashedLine(context, -x1 + y1, -x1, y1 - x1, z1 - x1); //xy-z竖
	drowDashedLine(context, 0, z1, -x1, -x1 + z1); //xz横
	drowDashedLine(context, 0, z1, y1, z1); //yz横
	drowDashedLine(context, -x1, -x1 + z1, y1 - x1, z1 - x1); //xz-y横
	drowDashedLine(context, y1, z1, y1 - x1, z1 - x1); //yz-x竖
}

/*
 *三维立方体（边框）绘制
 *提供三个三维向量(同顶点--原点)，以其为边，确定一个立方体
 *Thiree是否省略了三条基线(默认显示)
 *tintage是否涂色（默认涂色）
 *mycolor轮廓线条颜色（默认黑色）
 */
async function drowCubeXYZ(context, x1, y1, z1, x2, y2, z2, x3, y3, z3, Thiree, tintage, mycolor) {
	tintage = tintage == undefined ? true : tintage;
	if (tintage) {
		filleCubeXYZ(context, x1, y1, z1, x2, y2, z2, x3, y3, z3);
	}

	mycolor = mycolor == undefined ? "#000000" : mycolor;
	Thiree = Thiree == undefined ? true : Thiree;
	var axy = toChange(x1, y1, z1);
	var bxy = toChange(x2, y2, z2);
	var cxy = toChange(x3, y3, z3);
	var abcx = x1 + x2 + x3;
	var abcy = y1 + y2 + y3;
	var abcz = z1 + z2 + z3;
	var abcxy = toChange(abcx, abcy, abcz);
	var abx = axy[0] + bxy[0];
	var aby = axy[1] + bxy[1];
	var acx = axy[0] + cxy[0];
	var acy = axy[1] + cxy[1];
	var bcx = bxy[0] + cxy[0];
	var bcy = bxy[1] + cxy[1];
	if (Thiree) {
		context.save();
		context.globalAlpha = 0.3;
		drowLine(context, 0, 0, axy[0], axy[1], mycolor);
		drowLine(context, 0, 0, bxy[0], bxy[1], mycolor);
		drowLine(context, 0, 0, cxy[0], cxy[1], mycolor);
		context.restore();
	}
	drowLine(context, axy[0], axy[1], abx, aby, mycolor); //a-b
	drowLine(context, bxy[0], bxy[1], abx, aby, mycolor); //b-a
	drowLine(context, axy[0], axy[1], acx, acy, mycolor); //a-c
	drowLine(context, cxy[0], cxy[1], acx, acy, mycolor); //c-a
	drowLine(context, cxy[0], cxy[1], bcx, bcy, mycolor); //c-b
	drowLine(context, bxy[0], bxy[1], bcx, bcy, mycolor); //b-c
	drowLine(context, bcx, bcy, abcxy[0], abcxy[1], mycolor); //bc-a
	drowLine(context, acx, acy, abcxy[0], abcxy[1], mycolor); //ac-b
	drowLine(context, abx, aby, abcxy[0], abcxy[1], mycolor); //ab-c

}
/*
 *填涂立方体六个面（默认为灰色）
 */
function filleCubeXYZ(context, x1, y1, z1, x2, y2, z2, x3, y3, z3) {
	context.save();
	context.globalAlpha = 0.6;
	context.beginPath();
	var axy = toChange(x1, y1, z1);
	var bxy = toChange(x2, y2, z2);
	var cxy = toChange(x3, y3, z3);
	var abcx = x1 + x2 + x3;
	var abcy = y1 + y2 + y3;
	var abcz = z1 + z2 + z3;
	var abcxy = toChange(abcx, abcy, abcz);
	var abx = axy[0] + bxy[0];
	var aby = axy[1] + bxy[1];
	var acx = axy[0] + cxy[0];
	var acy = axy[1] + cxy[1];
	var bcx = bxy[0] + cxy[0];
	var bcy = bxy[1] + cxy[1];

	/*
	 *填涂ac平面
	 */
	context.fillStyle = "purple";
	context.moveTo(0, 0);
	context.lineTo(axy[0] * c1, -axy[1] * c1);
	context.lineTo(acx * c1, -acy * c1);
	context.lineTo(cxy[0] * c1, -cxy[1] * c1);
	context.lineTo(0, 0);
	context.fill();

	/*
	 *填涂bc平面
	 */
	context.fillStyle = "black";
	context.moveTo(0, 0);
	context.lineTo(cxy[0] * c1, -cxy[1] * c1);
	context.lineTo(bcx * c1, -bcy * c1);
	context.lineTo(bxy[0] * c1, -bxy[1] * c1);
	context.lineTo(0, 0);
	context.fill();

	/*
	 *填涂ab平面
	 */
	context.fillStyle = "green";
	context.moveTo(0, 0);
	context.lineTo(axy[0] * c1, -axy[1] * c1);
	context.lineTo(abx * c1, -aby * c1);
	context.lineTo(bxy[0] * c1, -bxy[1] * c1);
	context.lineTo(0, 0);
	context.fill();

	/*
	 *填涂a-bc平面
	 */
	/*
	context.fillStyle = "red";
	context.moveTo(axy[0]*c1,-axy[1]*c1);
	context.lineTo(acx*c1,-acy*c1);
	context.lineTo(abcxy[0]*c1,-abcxy[1]*c1);
	context.lineTo(abx*c1,-aby*c1);
	context.lineTo(axy[0]*c1,-axy[1]*c1);
	context.fill();
	*/

	/*
	 *填涂c-ab
	 */
	/*
		context.fillStyle = "blue";
		context.moveTo(cxy[0]*c1,-cxy[1]*c1);
		context.lineTo(acx*c1,-acy*c1);
		context.lineTo(abcxy[0]*c1,-abcxy[1]*c1);
		context.lineTo(bcx*c1,-bcy*c1);
		context.lineTo(cxy[0]*c1,-cxy[1]*c1);
		context.fill();
		*/

	/*
	 *填涂b-ac
	 */
	/*
	context.fillStyle = "gray";
	context.moveTo(bxy[0]*c1,-bxy[1]*c1);
	context.lineTo(abx*c1,-aby*c1);
	context.lineTo(abcxy[0]*c1,-abcxy[1]*c1);
	context.lineTo(bcx*c1,-bcy*c1);
	context.lineTo(bxy[0]*c1,-bxy[1]*c1);
	context.fill();
	*/

	context.closePath();
	context.restore();
}

/*
 *三维向量动态绘制(原点出发)
 *cube:是否显示立方体（默认显示）
 */
async function drow3DVector(context, x1, y1, z1, cube, color) {
	cube = cube == undefined ? true : cube;
	if (cube) {
		drowCube(context, x1, y1, z1);
	}
	var xy = toChange(x1, y1, z1);
	await drowVector3(context, xy[0], xy[1], 0, 0, color);
}

/*
 *三维向量绘制(动态)
 *从（x0,y0,z0）出发
 */
async function drow3DVector2(context, x0, y0, z0, x1, y1, z1, color) {
	var xy0 = toChange(x0, y0, z0);
	var xy1 = toChange(x1, y1, z1);
	await drowVector3(context, xy1[0], xy1[1], xy0[0], xy0[1], color);
}

/*
 *静态三维向量绘制（原点出发）
 */
function drow3DVector3(context, x1, y1, z1, color) {
	drowVector(context, -x1 + y1, -x1 + z1, color);
}

/*
 *静态三维向量绘制(x0,y0,z0) => (x1,y1,z1)
 */
function drow3DVector4(context, x0, y0, z0, x1, y1, z1, color) {
	drowLine(context, -x0 + y0, -x0 + z0, -x1 + y1, -x1 + z1, color);
}



/*
 *为三维向量添加文字
 */
function addFont_3D(context, text, x, y, z, fillStyle, font) {
	fillStyle = fillStyle == undefined ? "black" : fillStyle;
	font = font == undefined ? "bold italic 20pt Times new roman" : font;
	context.save();
	context.fillStyle = fillStyle;
	context.font = font;
	context.fillText(text, (y - x) * c1 + 2, -(z - x) * c1 + 2);
	context.restore();
}

/**
 * 绘制二维坐标轴
 * x轴长80*cunit
 * y轴与x轴等长
 *show是否显示数字刻度
 */
function drow2DAxes(context, show) {
	show = show == undefined ? true : show;
	context.save();
	context.beginPath();
	context.strokeStyle = "#000000";
	context.globalAlpha = 1;
	context.moveTo(mycanvas.width / 2, mycanvas.height / 2);
	context.lineTo(mycanvas.width - 10 * cunit, mycanvas.height / 2); //x轴右半边
	//以下是x轴右半边箭头绘制
	context.lineTo(mycanvas.width - 10 * cunit - 1 * cunit, mycanvas.height / 2 - 1 * cunit);
	context.moveTo(mycanvas.width - 10 * cunit, mycanvas.height / 2);
	context.lineTo(mycanvas.width - 10 * cunit - 1 * cunit, mycanvas.height / 2 + 1 * cunit);
	context.moveTo(mycanvas.width / 2, mycanvas.height / 2);

	context.lineTo(10 * cunit, mycanvas.height / 2); //x轴左半边
	context.moveTo(mycanvas.width / 2, mycanvas.height / 2);
	context.lineTo(mycanvas.width / 2, mycanvas.height - 10 * cunit); //y轴下部分
	context.moveTo(mycanvas.width / 2, mycanvas.height / 2);
	context.lineTo(mycanvas.width / 2, 10 * cunit); //y轴上部分
	//以下为y轴上部分箭头绘制
	context.lineTo(mycanvas.width / 2 - 1 * cunit, 10 * cunit + 1 * cunit);
	context.moveTo(mycanvas.width / 2, 10 * cunit);
	context.save();
	context.font = "15pt Times new roman";
	context.fillStyle = "black";
	context.fillText("y", mycanvas.width / 2 - 3 * cunit, 10 * cunit + cunit);
	context.fillText("x", mycanvas.width - 9 * cunit, mycanvas.height / 2 + 2 * cunit);
	context.restore();
	context.lineTo(mycanvas.width / 2 + 1 * cunit, 10 * cunit + 1 * cunit);

	if (show) {
		//以下是坐标刻度绘制
		//该循环绘制x轴刻度长度为60*cunit，
		context.font = "10pt Times new roman";
		context.fillStyle = "black";
		for (i = 20 * cunit, j = -10; i <= 80 * cunit; i += c1, j++) {
			context.moveTo(i, mycanvas.height / 2);
			context.lineTo(i, mycanvas.height / 2 - 1 * cunit);
			context.fillText(j, i - cunit, mycanvas.height / 2 + 3 * cunit, 8); //绘制刻度
		}

		//该循环绘制y轴刻度长度为60*cunit，
		for (i = 20 * cunit, j = 10; i <= 80 * cunit; i += c1, j--) {
			context.moveTo(mycanvas.width / 2, i);
			context.lineTo(mycanvas.width / 2 + 1 * cunit, i);
			if (j != 0) {
				context.fillText(j, mycanvas.width / 2 + 1 * cunit + cunit, i + cunit, 8); //绘制刻度
			}
		}
	}

	context.stroke();
	context.closePath();
	context.restore();
	context.translate(mycanvas.width / 2, mycanvas.height / 2); //改变坐标原点至画布中心
}

/*
 *绘制三维坐标轴网格及其刻度
 *最大值：13
 */
function drow3Dgrid(context) {
	context.save();
	context.font = "10pt Times new roman";
	var i = 1;
	context.strokeStyle = "red";
	while (i < 13) {
		drowDashedLine(context, i, 0, i, 13);
		drowDashedLine(context, 0, i, 13, i);
		drowDashedLine(context, i, 0, i - 13, -13, "red");
		drowDashedLine(context, -i, -i, -i + 13, -i, "red");
		drowDashedLine(context, -i, -i, -i, -i + 13, "blue");
		drowDashedLine(context, 0, i, -13, i - 13, "blue");
		context.fillText(i, i * c1 - 3, c1);
		context.fillText(i, -10, -i * c1);
		context.fillText(i, -i * c1, i * c1 + 8);
		i++;
	}
	context.restore();
}

/*
 *仅绘制三维坐标轴刻度
 */
function drow3DonlyScale(context) {
	context.save();
	context.font = "10pt Times new roman";
	context.strokeStyle = "red";
	let i = 1;
	while (i < 13) {
		drowDashedLine(context, i, 0, i, 1); //y轴
		drowDashedLine(context, 0, i, 1, i); //z轴
		drowDashedLine(context, -i, -i, -i + 1, -i); //x轴
		context.fillText(i, i * c1 - 6, c1); //y轴刻度
		context.fillText(i, -14, -i * c1); //z轴刻度
		context.fillText(i, -i * c1 + 2, i * c1 + 8); //x轴刻度
		i++;
	}
	context.restore();
}

/*
 *绘制三维四边形
 *由两个三维向量构成四边形并填涂颜色
 */
function drow3Dparallelogram(context, x1, y1, z1, x2, y2, z2, color) {
	color = color == undefined ? 'gray' : color;
	var xy1 = toChange(x1, y1, z1);
	var xy2 = toChange(x2, y2, z2);
	context.save();
	context.globalAlpha = 0.7;
	context.fillStyle = color;
	context.beginPath();
	context.moveTo(0, 0);
	context.lineTo(xy1[0] * c1, -xy1[1] * c1);
	context.lineTo(xy1[0] * c1 + xy2[0] * c1, -xy1[1] * c1 - xy2[1] * c1);
	context.lineTo(xy2[0] * c1, -xy2[1] * c1);
	context.lineTo(0, 0);
	context.fill();
	context.closePath();
	context.restore();
}

/*
 *绘制二维四边形
 *由两个二维向量构成平行四边形并涂色
 */
function drow2Dparallelogram(context, x1, y1, x2, y2, color) {
	var xx1 = x1 + x2;
	var yy1 = y1 + y2;
	color = color == undefined ? 'gray' : color;
	context.save();
	context.fillStyle = color;
	context.globalAlpha = 0.5;
	context.beginPath();
	context.moveTo(0, 0);
	context.lineTo(x1 * c1, -y1 * c1);
	context.lineTo(xx1 * c1, -yy1 * c1);
	context.lineTo(x2 * c1, -y2 * c1);
	context.lineTo(0, 0);
	context.fill();
	context.closePath();
	context.restore();
}

/*
 *绘制3D坐标轴
 *3D转换2D => (x1,y1,z1)=(-x1+y1,-x1+z1)
 *show:是否绘制数字刻度（默认true）
 */
function drow3DAxes(context, show) {
	show = show == undefined ? true : show;
	context.beginPath();
	context.strokeStyle = "#000000";
	context.font = "15pt Times new roman";
	context.moveTo(mycanvas.width / 2, mycanvas.height / 2);
	context.lineTo(mycanvas.width - 10 * cunit, mycanvas.height / 2); //y轴右半边
	/*
	 *箭头及坐标名称画法
	 */
	context.lineTo(mycanvas.width - 10 * cunit - 1 * cunit, mycanvas.height / 2 - 1 * cunit);
	context.moveTo(mycanvas.width - 10 * cunit, mycanvas.height / 2);
	context.lineTo(mycanvas.width - 10 * cunit - 1 * cunit, mycanvas.height / 2 + 1 * cunit);
	context.moveTo(mycanvas.width / 2, mycanvas.height / 2);
	context.fillText("Y", mycanvas.width - 10 * cunit, mycanvas.height / 2 + 5 * cunit);

	context.moveTo(mycanvas.width / 2, mycanvas.height / 2);
	context.lineTo(mycanvas.width / 2, 10 * cunit); //z轴上半轴
	//箭头及坐标名称画法
	context.lineTo(mycanvas.width / 2 - 1 * cunit, 11 * cunit);
	context.moveTo(mycanvas.width / 2, 10 * cunit);
	context.lineTo(mycanvas.width / 2 + 1 * cunit, 11 * cunit);
	context.fillText("Z", mycanvas.width / 2, 9 * cunit);
	context.moveTo(mycanvas.width / 2, mycanvas.height / 2);
	context.lineTo(10 * cunit, mycanvas.height - 10 * cunit); //X轴正向画法
	//箭头及坐标名称画法
	context.fillText("X", 15 * cunit, mycanvas.height - 10 * cunit);
	context.lineTo(12 * cunit, mycanvas.height - 10 * cunit);
	context.moveTo(10 * cunit, mycanvas.height - 10 * cunit);
	context.lineTo(10 * cunit, mycanvas.height - 12 * cunit);
	context.stroke();
	context.closePath();
	context.translate(mycanvas.width / 2, mycanvas.height / 2);
	if (show) {
		drow3DonlyScale(context);
	}

}

/*
 *清除画布，并重新根据维度（dim）显示坐标轴
 *vdim:维度
 *show:刻度是否显示（默认显示）
 */
function clearCanvas(context, dim, show) {
	show = show == undefined ? true : show;
	context.clearRect(-mycanvas.width / 2, -mycanvas.height / 2, mycanvas.width, mycanvas.height);
	context.save();
	context.translate(-mycanvas.width / 2, -mycanvas.height / 2);
	context.lineWidth = 1;
	context.fillStyle = "black";
	context.font = "10pt Times new roman";
	if (dim == 2) {
		drow2DAxes(context, show);
	} else if (dim == 3) {
		drow3DAxes(context, show);
	}
	context.restore();
}

/*
 *计算三阶行矩阵的值
 */
function threeDet(Arrage) {
	var result = Arrage[0][0] * Arrage[1][1] * Arrage[2][2] + Arrage[0][1] * Arrage[1][2] * Arrage[2][0] +
		Arrage[0][2] * Arrage[1][0] * Arrage[2][1] - Arrage[0][2] * Arrage[1][1] * Arrage[2][0] -
		Arrage[0][1] * Arrage[1][0] * Arrage[2][2] - Arrage[0][0] * Arrage[1][2] * Arrage[2][1];
	return result;
}

/*
 *保留x的小数点后n位数
 */
function toFloat(x, n) {
	var x = Math.round(x * Math.pow(10, n)) / Math.pow(10, n);
	return x;
}

/*
 * 检查（x,y）是否超出现有宽高范围
 * 超出范围，适当缩小图片
 * 并取消刻度
 */
function checkAxes(canvas, context, x, y, dim) {
	var ff = false;
	var x1 = 1;
	var y1 = 1;
	if (Math.abs(x * c1) >= canvas.width / 2) {
		x1 = (canvas.width / 2) / (x * c1) - (canvas.width / 2) / (x * c1) / 5;
		y1 = x1;
		ff = true;
	}
	if (Math.abs(y * c1) >= canvas.height / 2) {
		y1 = (canvas.height / 2) / (y * c1) - (canvas.height / 2) / (y * c1) / 5;
		if (x1 < y1) {
			y1 = x1;
		} else {
			x1 = y1;
		}
		ff = true;
	}
	if (ff) {
		clearCanvas(context, dim, false);
		context.scale(x1, y1);
	}
	return ff;
}

/*
 *input(type=text)输入内容提示
 *输出input对象的value属性(input必需设置name属性值)
 *需要绑定到input对象的mouseover事件中触发
 */
function hint(event) {
	let myBoxDiv = document.getElementById("mybox");
	if (myBoxDiv) {
		myBoxDiv.style.display = "none";
		document.body.removeChild(myBoxDiv);
	}
	event = event || window.event;
	let x = event.pageX;
	let y = event.pageY;
	myBoxDiv = document.createElement("div");
	myBoxDiv.id = "mybox";
	myBoxDiv.style.position = "absolute"
	myBoxDiv.style.top = y - 20 + "px";
	myBoxDiv.style.left = x + 20 + "px";
	myBoxDiv.style.backgroundColor = "rgba(117, 122, 117,0.3)";
	myBoxDiv.style.border = "1px solid black"
	myBoxDiv.style.width = "auto";
	myBoxDiv.style.height = "20px";
	myBoxDiv.style.color = "black";
	myBoxDiv.style.fontSize = "15px";
	myBoxDiv.innerHTML = "&nbsp;" + this.name + "= " + this.value + "&nbsp;";
	document.body.appendChild(myBoxDiv);
	this.onmouseout = function (e) {
		myBoxDiv.style.display = "none";
		document.body.removeChild(myBoxDiv);
	}
}